package com.zmn.oms.admin.controller.report.ordered;

import com.google.common.collect.Maps;
import com.zmn.common.dto.LayuiTableResponseDTO;
import com.zmn.common.dto.VtDTO;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.office.excel.ExportExcelBuilder;
import com.zmn.consts.GlobalConsts;
import com.zmn.mcc.cas.model.LoginStaff;
import com.zmn.mcc.common.dto.dept.DeptDRO;
import com.zmn.mcc.common.dto.staff.StaffQueryDIO;
import com.zmn.mcc.dubbo.interfaces.dept.DeptListRemoteService;
import com.zmn.mcc.dubbo.interfaces.staff.StaffListRemoteService;
import com.zmn.oms.model.entity.report.ReportOrderedQuery;
import com.zmn.oms.model.vo.report.ReportOrderedVO;
import com.zmn.oms.services.interfaces.report.ReportOrderedService;
import com.zmn.performance.common.exception.RpcResultException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 录单报表页面跳转控制器
 *
 * @author hankangshuai
 * @since 2019-7-9
 */
@Slf4j
@Controller
@RequestMapping("/report/ordered/")
public class ReportOrderedListController extends ReportOrderedBaseController {

    public static final int PLAT_OPERATION_DEPT_ID = 4387;

    public static final int ONLINE_CUSTOMER_DEPT_ID = 2041;

    public static final int CALL_CENTER_DEPT_ID = 2044;

    public static final int MAX_STAFF_SIZE = 1000;

    public static final int ORDER_MANAGE_DEPT_ID = 2043;
    public static final int QUALITY_CONTROL_DEPARTMENT_DEPT_ID = 2017;

    @Resource
    private ReportOrderedService reportOrderedService;

    @Reference(check = false, version = com.zmn.mcc.dubbo.dto.DubboConsts.INTERFACE_VERSION)
    DeptListRemoteService deptListRemoteService;
    @Reference(check = false, version = com.zmn.mcc.dubbo.dto.DubboConsts.INTERFACE_VERSION)
    StaffListRemoteService staffListRemoteService;

    /**
     * 录单报表异步数据加载(分页)
     */
    @ResponseBody
    @RequestMapping(value = "loadData")
    public LayuiTableResponseDTO loadData(ReportOrderedQuery query) {
        queryProcess(query);
        List<ReportOrderedVO> reportOrderedVOS = this.reportOrderedService.listPageByQuery(query);
        LayuiTableResponseDTO<ReportOrderedVO> success = LayuiTableResponseDTO.success(query.getTotalCount(), reportOrderedVOS);
        success.setExtData(reportOrderedService.getTotalLine(query));
        return success;
    }

    /**
     * 录单报表导出
     */
    @RequestMapping(value = "export")
    public void export(ReportOrderedQuery query, HttpServletResponse response) throws Exception {
        queryProcess(query);
        LoginStaff currentStaff = getCurrentStaff();
        Integer exportLimit = currentStaff.getExportLimit();
        query.setPageSize(exportLimit);
        List<ReportOrderedVO> reportOrderedVOS = this.reportOrderedService.listPageByQuery(query);
        List<Integer> deptIds = reportOrderedVOS.stream().map(ReportOrderedVO::getDeptId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        Map<Integer, String> deptMap = getDeptMap(deptIds);
        LinkedHashMap<String, String> fieldMap = Maps.newLinkedHashMap();
        fieldMap.put("allDeptCallBack", "部门");
        fieldMap.put("receiverName", "录入人");
        fieldMap.put("totalCount", "总单量");
        fieldMap.put("totalNewCount", "新单汇总");
        fieldMap.put("newCount", "新单");
        fieldMap.put("reworkCount", "返修");
        fieldMap.put("newWithDuplicateCount", "新单重复");
        fieldMap.put("reworkWithDuplicateCount", "返修重复");
        fieldMap.put("doingCount", "进行中");
        fieldMap.put("discardCount", "弃单");
        fieldMap.put("failCount", "失败");
        fieldMap.put("discardRate", "弃单率");
        fieldMap.put("failRate", "失败率");
        fieldMap.put("successRate", "成功率");
        fieldMap.put("totalAmountSumStr", "应收总额");
        ExportExcelBuilder exportExcelBuilder = new ExportExcelBuilder();
        ExportExcelBuilder.ExcelSheet<ReportOrderedVO> excelSheet = exportExcelBuilder.createExcelSheet("录单报表导出", reportOrderedVOS, fieldMap, false, true);
        excelSheet.setCallback((fieldName, entity) -> {
            switch (fieldName) {
                case "allDeptCallBack":
                    Integer deptId = entity.getDeptId();
                    return Optional.ofNullable(deptMap.get(deptId)).orElse("未知部门");
                case "totalAmountSumStr":
                    return entity.getTotalAmountSumStr();
                default:
                    return null;
            }
        });
        excelSheet.builderData();
        exportExcelBuilder.exportExcel(response, "录单报表导出");
    }

    private Map<Integer, String> getDeptMap(List<Integer> deptIds) {
        if (deptIds.isEmpty()) {
            return Collections.emptyMap();
        }
        ResponseDTO<List<DeptDRO>> deptByDept = deptListRemoteService.listDeptByDeptIds(deptIds);
        if (!deptByDept.isSuccess()) {
            throw new RuntimeException("deptListRemoteService.listDeptByDeptIds 调用失败");
        }
        List<DeptDRO> data = Optional.ofNullable(deptByDept.getData()).orElse(Collections.emptyList());
        return data.stream().collect(Collectors.toMap(DeptDRO::getDeptId, DeptDRO::getDeptName));
    }

    /**
     * 录单报表页面跳转
     *
     * @return
     */
    @RequestMapping("list")
    public ModelAndView list() {
        ModelAndView mv = new ModelAndView("report/ordered/list");
        //查询呼叫中心，包含2044以及其下所有的部门
        String callCenterChildDeptStr = getCenterDeptIdArrString(CALL_CENTER_DEPT_ID);
        //查询网络客服组，包含2041以及其下所有的部门
        String onlineCustomerSubDeptStr = getCenterDeptIdArrString(ONLINE_CUSTOMER_DEPT_ID);
        //查询平台运营组，包含4391以及其下所有的部门
        String platformOperationsSubDeptStr = getCenterDeptIdArrString(PLAT_OPERATION_DEPT_ID);
        // 查询订单管理,包含2043以及旗下所有的部门
        String orderManageDeptId = getCenterDeptIdArrString(ORDER_MANAGE_DEPT_ID);
        // 查询品控部,包含2017以及旗下所有的部门
        String qualityControlDepartmentDeptId = getCenterDeptIdArrString(QUALITY_CONTROL_DEPARTMENT_DEPT_ID);
        mv.addObject("callCenterChildDept", callCenterChildDeptStr);
        mv.addObject("onlineCustomerSubDept", onlineCustomerSubDeptStr);
        mv.addObject("platformOperationsSubDept", platformOperationsSubDeptStr);
        mv.addObject("orderManageDeptId", orderManageDeptId);
        mv.addObject("qualityControlDepartmentDeptId", qualityControlDepartmentDeptId);
        return mv;
    }

    private String getCenterDeptIdArrString(int i) {
        //noinspection rawtypes
        ResponseDTO<List<DeptDRO>> listResponseDTO = deptListRemoteService.listDeptByParentId(i, GlobalConsts.YES);
        if (!listResponseDTO.isSuccess()) {
            throw new RpcResultException("deptListRemoteService.listDeptVtByParentId", listResponseDTO, i);
        }
        //noinspection unchecked
        List<DeptDRO> list = Optional.ofNullable(listResponseDTO.getData()).orElse(Collections.emptyList());
        return Stream.concat(Stream.of(i).map(Objects::toString), list.stream().map(DeptDRO::getDeptId).map(Objects::toString))
                .collect(Collectors.joining(","));
    }

    private List<VtDTO> getZmnOperatorList() {

        StaffQueryDIO query = new StaffQueryDIO();
        query.setPlat(GlobalConsts.PLAT_MARK_ZMN);
        ResponseDTO<List<VtDTO>> response = staffListRemoteService.listStaffVtByQueryDIO(query);
        if (!response.isSuccess() || CollectionUtils.isEmpty(response.getData())) {
            return Collections.emptyList();
        }
        return response.getData();

    }

    /**
     * 公用查询条件处理
     *
     * @param query
     */
    private void queryProcess(ReportOrderedQuery query) {
        //部门翻译成录入人
        List<Integer> deptIds = query.getDeptId();
        // deptId!=null 部门ID翻译成员工ID并与以选择的员工作交集
        if (CollectionUtils.isNotEmpty(deptIds)) {
            List<Integer> staffIdByDept = deptIds.stream().flatMap(integer -> {
                ResponseDTO<List<VtDTO>> staffByDeptIds = staffListRemoteService.listStaffVtByDeptIdsAndNumber(Collections.singletonList(integer), null, MAX_STAFF_SIZE);
                if (!staffByDeptIds.isSuccess()) {
                    throw new RuntimeException("staffListRemoteService.listStaffVtByDeptIdsAndNumber,接口调用失败！");
                }
                return Optional.ofNullable(staffByDeptIds.getData()).orElseGet(Collections::emptyList).stream().map(VtDTO::getValue);
            }).collect(Collectors.toList());
            List<Integer> receiverId = query.getReceiverId();
            if (CollectionUtils.isEmpty(receiverId)) {
                query.setReceiverId(staffIdByDept);
            } else {
                receiverId.retainAll(staffIdByDept);
            }
        }
        //默认往前三十天
        Date startDate = query.getStartDate();
        Date endDate = query.getEndDate();
        Calendar calendar = Calendar.getInstance();
        if (Objects.isNull(startDate)) {
            calendar.setTime(new Date());
            calendar.add(Calendar.DAY_OF_MONTH, -30);
            calendar.set(Calendar.HOUR, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            query.setStartDate(calendar.getTime());
        } else {
            calendar.setTime(startDate);
            calendar.set(Calendar.HOUR, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
            query.setStartDate(calendar.getTime());
        }
        if (Objects.isNull(endDate)) {
            calendar.setTime(new Date());
            calendar.set(Calendar.HOUR, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            calendar.set(Calendar.MILLISECOND, 999);
            query.setStartDate(calendar.getTime());
        } else {
            calendar.setTime(endDate);
            calendar.set(Calendar.HOUR, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            calendar.set(Calendar.MILLISECOND, 999);
            query.setEndDate(calendar.getTime());
        }
    }

}




